﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace GameTesting
{
    

    class ObjLoader
    {
        private static int s_current_group_id = 0;
        private static ResourceSystem.load_delegate<ResourceSystem.Resource> loader = ObjLoader.load;

        public ObjLoader()
        {
        }

        public static ResourceSystem.load_delegate<ResourceSystem.Resource> Loader
        {
            get { return loader; }
        }

        private static void load(string path, List<ResourceSystem.Resource> object_meshes)
        {
            string[] file_lines = File.ReadAllLines(path);

            ++s_current_group_id;
            ObjectMesh obj = null;
            int vertex_count = 0;
            int normal_count = 0;

            foreach (string line in file_lines)
            {
                string[] line_parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                if (line_parts.Length > 0)
                {
                    string line_type = line_parts[0];

                    switch (line_type)
                    {
                        case "#": //Comments
                            {
                                break;
                            }

                        case "o":
                            {
                                if (obj != null)
                                {
                                    obj.buildVertices();
                                }

                                int last_slash = path.LastIndexOfAny(new char[] { '/', '\\' });
                                if (last_slash == -1)
                                    last_slash = 0;

                                int last_dot = path.LastIndexOf('.');
                                string modelName = path.Substring(last_slash, last_dot);

                                obj = new ObjectMesh();
                                obj.Name = line_parts[1];
                                obj.GroupName = modelName;
                                object_meshes.Add(obj);
                                break;
                            }

                        case "v":
                            {
                                ++vertex_count;
                                obj.addVertex(new Vector3(Convert.ToSingle(line_parts[1]),
                                                          Convert.ToSingle(line_parts[2]),
                                                          Convert.ToSingle(line_parts[3])), 
                                                          vertex_count);
                                break;
                            }

                        case "vn":
                            {
                                ++normal_count;
                                obj.addNormal(new Vector3(Convert.ToSingle(line_parts[1]),
                                                          Convert.ToSingle(line_parts[2]),
                                                          Convert.ToSingle(line_parts[3])),
                                                          normal_count);
                                break;
                            }

                        case "f":
                            {
                                obj.addFace(parseFace(line_parts));
                                break;
                            }

                        default:
                            {
                                break;
                            }
                    }
                }
            }

            //Build the final object in the list
            if (obj != null)
            {
                obj.buildVertices();
            }
        }

        private static Face parseFace(string[] line_parts)
        {
            Face f = new Face();

            for (int i = 1; i < line_parts.Length; ++i)
            {
                string[] group_parts = line_parts[i].Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

                //Vertex only
                if (group_parts.Length == 1)
                {
                    f.VertexIndices.Add( Convert.ToInt32(group_parts[0]));
                }
                else if (group_parts.Length == 2) //Vertex and normals
                {
                    f.VertexIndices.Add(Convert.ToInt32(group_parts[0]));
                    f.NormalIndices.Add(Convert.ToInt32(group_parts[1]));
                }
                else //Vertex, texture, and normals
                {
                    f.VertexIndices.Add(Convert.ToInt32(group_parts[0]));
                    f.TextureIndices.Add(Convert.ToInt32(group_parts[1]));
                    f.NormalIndices.Add(Convert.ToInt32(group_parts[2]));
                }

            }

            return f;
        }
    }
}
